#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <malloc.h>
void print_file_stat(char *);
void file_type(char *);
void file_permission(char *);
void file_access(char*);
int main(int argc,char *argv[])
{
	if(argc < 2)
	{
		printf("incorrect parameter\n");
		return 0;
	}
	// print_file_stat("/etc/passwd");
	// file_type(argv[1]);
	// file_permission(argv[1]);
	file_access(argv[1]);
	return 0;
}
void file_access(char* path)
{
	if(access(path,F_OK) == -1)
	{
		printf("%s does not exist\n",path);
		return;
	}
	if(access(path,R_OK) == -1)
	{
		printf("%d cannot read file:%s\n",getpid(),path);
	}
	if(access(path,W_OK) == -1)
	{
		printf("%d cannot write file:%s\n",getpid(),path);
	}
	if(access(path,X_OK) == -1)
	{
		printf("%d cannot excute file:%s\n",getpid(),path);
	}
}
void file_permission(char* path)
{
	struct stat s;
	if(lstat(path,&s) == -1)
	{
		perror("incorret file");
		return;
	}
	printf("%c%c%c%c%c%c%c%c%c\n"
		,(S_IRUSR & s.st_mode) ? 'r' : '-'
		,(S_IWUSR & s.st_mode) ? 'w' : '-'
		,(S_IXUSR & s.st_mode) ? 'x' : '-'
		,(S_IRGRP & s.st_mode) ? 'r' : '-'
		,(S_IWGRP & s.st_mode) ? 'w' : '-'
		,(S_IXGRP & s.st_mode) ? 'x' : '-'
		,(S_IROTH & s.st_mode) ? 'r' : '-'
		,(S_IWOTH & s.st_mode) ? 'w' : '-'
		,(S_IXOTH & s.st_mode) ? 'x' : '-'
	);
}
void file_type(char* path)
{
	struct stat s;
	if(lstat(path,&s) == -1)
	{
		perror("incorrect file");
		return;
	}
	char* str = "unknow type";
	if(S_ISREG(s.st_mode))
	{
		str = "regular file";
	}
	else if(S_ISDIR(s.st_mode))
	{
		str = "directory";
	}
	else if(S_ISBLK(s.st_mode))
	{
		str = "block special file";
	}
	else if(S_ISCHR(s.st_mode))
	{
		str = "character special file";
	}
	else if(S_ISFIFO(s.st_mode))
	{
		str = "FIFO";
	}
	else if(S_ISSOCK(s.st_mode))
	{
		str = "socket file";
	}
	else if(S_ISLNK(s.st_mode))
	{
		str = "symbolic link";
	}
	printf("%s : %s\n",path,str);
}
void print_file_stat(char* path)
{
	struct stat* s = malloc(sizeof(struct stat));
	if(stat(path,s) == -1)
	{
		perror("incorrect file : ");
	}
	printf("mode \t %d\nino \t %d\ndev \t %d\nrdev \t %d\nnlink \t %d\nuid \t %d\ngid \t %d\nsize \t %d\natime \t %d\nmtime \t %d\nctime \t %d\nblksize \t %d\nblocks \t %d\n",
		(int)s->st_mode,(int)s->st_ino,(int)s->st_dev,(int)s->st_rdev,(int)s->st_nlink,(int)s->st_uid,(int)s->st_gid,(int)s->st_size,(int)s->st_atime,(int)s->st_mtime,(int)s->st_ctime,(int)s->st_blksize,(int)s->st_blocks);
	free(s);
}
